/*   Copyright (c) 2008, Brian Griffiths
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions are met:
 *       * Redistributions of source code must retain the above copyright
 *         notice, this list of conditions and the following disclaimer.
 *       * Redistributions in binary form must reproduce the above copyright
 *         notice, this list of conditions and the following disclaimer in the
 *         documentation and/or other materials provided with the distribution.
 *       * Neither the name of Brian Griffiths nor the
 *         names of this packages contributors may be used to endorse or promote products
 *         derived from this software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY Brian Griffiths ``AS IS'' AND ANY
 *   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *   DISCLAIMED. IN NO EVENT SHALL Brian Griffiths BE LIABLE FOR ANY
 *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef BREADCRUMBS_H_
#define BREADCRUMBS_H_

#define DIR_SCALE 1  /* scaling applied to each direction angle (in degrees) */
#define DIR_RES   9  /* number of bits required to store a direction reading scaled with DIR_SCALE */
#define STEP_SIZE 15 /* number of decimal (scaled) degrees moved before a reading is taken (min val 15)*/

/* Example values
 * scale 23, dir_res 4, step_size 100 - high compression, "zig-zaging" tracks, corners cut
 *   "   12     "    5      "     40  - good approximation, tight corners cut
 *   "   1      "    9      "     20  - best approximation, small errors, low(er) compression ratio (357:1 from raw nmea!)
 */

/* DO NOT MODIFY ANYTHING BELOW THIS LINE */

#define POS_MULT 100000.0 /* used to multiply decimal degrees value to make a (useful) integer for math */
//#define FULL_RES 25 /* number of bits required to store a first fix latitude or longitude reading, ensure 1 space for msb signed bit */
//TODO FULL_RES 25 seems to use 24 bits
#define FULL_RES 32 /* number of bits required to store a first fix latitude or longitude reading, ensure 1 space for msb signed bit */

#define EEPROM_SIZE 512

typedef struct _gpsPos
{
    float lat;
    float lon;
    float direction; /* The angle of the vector occupied by this position and the last relative to north */
    float norm_dir;
    int quad;
} gpsPos;

#ifndef M_PI
#define M_PI        3.14159265358979323846
#endif

#define RAD2DEG(_a) (_a * (180.0 / M_PI))
#define DEG2RAD(_a) (_a * (M_PI / 180.0))
#define SETBIT(_data,_bit) _data |=(1<<_bit)
#define UNSETBIT(_data,_bit) _data &= ~(1<<_bit)

#define KML_STRING1 \
"<kml>\n" \
"<Placemark>\n" \
"<Style id=\"lineStyle\">\n" \
"<LineStyle>\n" \
"<color>800000ff</color>\n" \
"<width>10</width>\n" \
"</LineStyle>\n" \
"</Style>\n" \
"<Point>\n" \
"<coordinates>"
//put first fix here

#define KML_STRING2 \
"</coordinates>\n" \
"</Point>\n" \
"<LineString>\n" \
"<coordinates>\n" \

//put lots of positions here

#define KML_STRING3 \
"</coordinates>\n" \
"</LineString>\n" \
"</Placemark>\n" \
"</kml>\n\n\n"

/************************************************************/
/* Function decelerations                                   */

void gpsEncodePosition(float lat, float lon);
void gpsDecodeEeprom(void);

void gpsCalcHeading(gpsPos *prev, gpsPos *cur);
void gpsAddDir(float *lat, float *lon, unsigned int dir);
float gpsDm2Dec(float dms);
char gpsCheckEnd(void);
void gpsReadEeprom(void *data, int nBits);
void gpsWriteEeprom(void *data, int nBits);


char    _d_str[11]; /* used by EE_WRITE_D to store output string */

#define EE_READ(_a)		    EEPROM.read(_a)
#define EE_WRITE(_d, _a)    EEPROM.write(_a, _d)
#define SER_WRITE(_d)	    Serial.print(_d)
#define SER_WRITE_A(_a)     Serial.print(_a)
#define SER_WRITE_D(_f)     Serial.print(dtostrf((float)_f,10,6,_d_str));
#define SER_READ(_d)	    _d = Serial.read()

#endif /* BREADCRUMBS_H_ */
